package cn.donting.jme.swing.tab;

import cn.donting.jme.EditorContent;
import cn.donting.jme.editor.scene.Scene;
import cn.donting.jme.event.file.OpenFileEvent;
import cn.donting.jme.expansion.file.FileIcon;
import cn.donting.jme.project.Project;
import cn.donting.jme.swing.JDragPanel;
import cn.donting.jme.swing.dialog.CreateJ3mDialog;
import cn.donting.jme.swing.drag.FileTransferable;
import cn.donting.jme.swing.layout.Anchor;
import cn.donting.jme.swing.layout.AnchorLayout;
import cn.donting.jme.swing.Tab;
import cn.donting.jme.utile.JFileUtil;
import cn.donting.jme.utile.SaveUtil;
import cn.hutool.core.io.FileUtil;
import com.formdev.flatlaf.extras.FlatSVGIcon;
import lombok.extern.slf4j.Slf4j;
import org.jdesktop.swingx.HorizontalLayout;
import org.jdesktop.swingx.WrapLayout;

import javax.swing.*;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreePath;
import java.awt.*;
import java.awt.datatransfer.Transferable;
import java.awt.event.*;
import java.io.File;
import java.io.IOException;

@Slf4j
public class ProjectTab extends Tab {
    private Project project;

    private FileSystemModel fileSystemModel;
    private JTree jTree;
    private FileViewPanel fileViewPanel;
    private JPanel fileViewRootPanel;
    private JPanel fileViewPathPanel;
    private JToolBar fileViewPathBar;
    public ProjectTab(Project project) {
        this.project = project;
        fileViewPanel = new FileViewPanel();
        fileViewRootPanel = new JPanel();
        fileViewRootPanel.setLayout(new BorderLayout());
        fileViewPathPanel=new JPanel();
        fileViewPathPanel.setLayout(new HorizontalLayout());
        fileViewPathBar=new JToolBar();
        fileViewPathPanel.add(fileViewPathBar);

        setTitle("Project");
        setIcon(new FlatSVGIcon("icon/projectTab.svg"));
        setLayout(new BorderLayout());
        JSplitPane jSplitPane = new JSplitPane();
        add(jSplitPane, BorderLayout.CENTER);
        jSplitPane.setDividerLocation(200);
        JScrollPane leftScrollPane = new JScrollPane();
        JScrollPane rightScrollPane = new JScrollPane();

        fileViewRootPanel.add(rightScrollPane,BorderLayout.CENTER);
        fileViewRootPanel.add(fileViewPathPanel,BorderLayout.NORTH);

        jSplitPane.setLeftComponent(leftScrollPane);
        rightScrollPane.setViewportView(fileViewPanel);
        jSplitPane.setRightComponent(fileViewRootPanel);

        jTree = new JTree();
        jTree.setDragEnabled(true);
        jTree.setTransferHandler(new FileTransferHandler());
        fileSystemModel = new FileSystemModel(project.getSrcMainDir());
        jTree.setModel(fileSystemModel);
        jTree.setCellRenderer((tree, value, selected, expanded, leaf, row, hasFocus) -> {
            JLabel label = new JLabel(value.toString());
            if (value instanceof DefaultMutableTreeNode) {
                File file = (File) ((DefaultMutableTreeNode) value).getUserObject();
                label.setIcon(getFileIcon(file));
                label.setText(file.getName());
            }
            return label;
        });

        leftScrollPane.setViewportView(jTree);
        jTree.addMouseListener(new MouseAdapter() {
            @Override
            public void mousePressed(MouseEvent e) {
                if (SwingUtilities.isRightMouseButton(e)) {
                    // 获取右键点击的路径
                    TreePath path = jTree.getClosestPathForLocation(e.getX(), e.getY());
                    if (path != null) {
                        jTree.setSelectionPath(path);
                        jTree.requestFocus();
                    }
                    FileMutableTreeNode lastPathComponent = (FileMutableTreeNode) path.getLastPathComponent();
                    File file = lastPathComponent.file;
                    if (FileUtil.isSub(project.getSrcResourcesDir(), file)) {
                        showResourcesPopupMenu(lastPathComponent, e);
                    } else if (FileUtil.isSub(project.getSrcJavaDir(), file)) {
                        showResourcesPopupMenu(lastPathComponent, e);
                    }
                    return;
                }
                if (SwingUtilities.isLeftMouseButton(e) && e.getClickCount() == 2) {
                    TreePath selectionPath = jTree.getSelectionModel().getSelectionPath();
                    FileMutableTreeNode lastPathComponent = (FileMutableTreeNode) selectionPath.getLastPathComponent();
                    OpenFileEvent openFileEvent = new OpenFileEvent(lastPathComponent.file);
                    EditorContent.postEvent(openFileEvent);
                }
            }
        });

        jTree.addTreeSelectionListener(this::treeSSelectChanged);


    }


    private void treeSSelectChanged(TreeSelectionEvent e) {
        TreePath selectionPath = jTree.getSelectionPath();
        FileMutableTreeNode fileMutableTreeNode = (FileMutableTreeNode) selectionPath.getLastPathComponent();
        File file = fileMutableTreeNode.file;
        if (file.isDirectory()) {
            fileViewPanel.setFile(fileMutableTreeNode);
        }
    }

    /**
     * 显示 Resources 目录下 的 tree 右键菜单
     *
     * @param fileMutableTreeNode
     * @param event
     */
    private void showResourcesPopupMenu(FileMutableTreeNode fileMutableTreeNode, MouseEvent event) {
        JPopupMenu popupMenu = new JPopupMenu();
        JMenuItem refresh = new JMenuItem("刷新");
        refresh.setEnabled(fileMutableTreeNode.file.isDirectory());
        refresh.setIcon(new FlatSVGIcon("icon/refresh.svg"));
        refresh.addActionListener(e -> {
            fileMutableTreeNode.removeAllChildren();
            FileSystemModel.buildTree(fileMutableTreeNode);
            fileSystemModel.nodeStructureChanged(fileMutableTreeNode);
            this.treeSSelectChanged(null);
        });
        popupMenu.add(refresh);
        popupMenu.add(new JPopupMenu.Separator());

        JMenu newFile = new JMenu("新建");

        JMenuItem newScene = new JMenuItem("场景(scene)");
        newScene.addActionListener(e -> {
            Scene scene = Scene.newInstance();
            try {
                SaveUtil.save(new File(fileMutableTreeNode.file, "new.scene"), scene);
                fileMutableTreeNode.removeAllChildren();
                ProjectTab.FileSystemModel.buildTree(fileMutableTreeNode);
                fileSystemModel.nodeStructureChanged(fileMutableTreeNode);
                this.treeSSelectChanged(null);
            } catch (IOException ex) {
                throw new RuntimeException(ex);
            }
        });

        JMenuItem j3d = new JMenuItem("材质(j3m)");
        j3d.addActionListener(e -> {
            File file = new CreateJ3mDialog(fileMutableTreeNode.file).showDialog();
            if (file != null) {
                fileMutableTreeNode.removeAllChildren();
                ProjectTab.FileSystemModel.buildTree(fileMutableTreeNode);
                fileSystemModel.nodeStructureChanged(fileMutableTreeNode);
                this.treeSSelectChanged(null);
            }
        });

        newFile.add(newScene);
        newFile.add(j3d);
        popupMenu.add(newFile);
        popupMenu.add(new JPopupMenu.Separator());


        popupMenu.show((JComponent) event.getSource(), event.getX(), event.getY());
    }

    private void showJavaPopupMenu(File file, int x, int y) {
        PopupMenu popupMenu = new PopupMenu();

    }

    public Icon getFileIcon(File file) {
        return FileIcon.getFileIcon(file, 16);
    }

    @Override
    public void setLoading() {

    }

    public static class FileMutableTreeNode extends DefaultMutableTreeNode {
        public final File file;

        public FileMutableTreeNode(File file) {
            super(file);
            this.file = file;
        }
    }

    private static class FileSystemModel extends DefaultTreeModel {
        public FileSystemModel(File root) {
            super(new FileMutableTreeNode(root));
            buildTree((FileMutableTreeNode) getRoot());
        }

        // 递归构建文件系统树
        public static void buildTree(FileMutableTreeNode parentNode) {
            File file = parentNode.file;
            if (file.isDirectory()) {
                File[] files = file.listFiles();
                if (files != null) {
                    JFileUtil.sort(files);
                    for (File child : files) {
                        FileMutableTreeNode childNode = new FileMutableTreeNode(child);
                        parentNode.add(childNode);
                        buildTree(childNode);
                    }
                }
            }
        }

        // 重写 isLeaf 方法以判断节点是否是叶子节点
        @Override
        public boolean isLeaf(Object node) {
            FileMutableTreeNode fileMutableTreeNode = (FileMutableTreeNode) node;
            return fileMutableTreeNode.file.isFile();
        }
    }

    /**
     * 文件view,大图
     */
    private class FilePanel extends JDragPanel {
        private final FileMutableTreeNode fileMutableTreeNode;

        /**
         * 属于哪个 FileMutableTreeNode
         *
         * @param fileMutableTreeNode
         */
        public FilePanel(FileMutableTreeNode fileMutableTreeNode) {
            this.fileMutableTreeNode = fileMutableTreeNode;
            setLayout(new AnchorLayout());
            setPreferredSize(new Dimension(80, 90));
            JLabel icon = new JLabel();
            icon.setIcon(FileIcon.getFileIcon(fileMutableTreeNode.file, 60));
            add(icon, new Anchor(5, 10, 5, 10));
            addMouseListener(new MouseAdapter() {
                @Override
                public void mouseEntered(MouseEvent e) {
                    setBackground(UIManager.getColor("Tree.selectionBackground"));
                }

                @Override
                public void mouseExited(MouseEvent e) {
                    setBackground(null);
                }

                @Override
                public void mouseClicked(MouseEvent e) {
                    if (e.getClickCount() == 2 && SwingUtilities.isLeftMouseButton(e)) {
                        if (fileMutableTreeNode.file.isDirectory()) {
                            fileViewPanel.setFile(fileMutableTreeNode);
                        } else {
                            OpenFileEvent openFileEvent = new OpenFileEvent(fileMutableTreeNode.file);
                            EditorContent.postEvent(openFileEvent);
                        }
                    }
                }
            });
            JLabel text = new JLabel();
            text.setText(fileMutableTreeNode.file.getName());
            // 设置文本水平和垂直居中
            text.setHorizontalAlignment(JLabel.CENTER);
            text.setVerticalAlignment(JLabel.CENTER);
            add(text, new Anchor(72, 2, 2, 0));
            setTransferHandler(new FileTransferHandler());
        }


    }

    /**
     * jtree 文件拖动 的 transferHandle
     */
    private class FileTransferHandler extends TransferHandler {

        @Override
        public int getSourceActions(JComponent c) {
            return TransferHandler.LINK;
        }

        @Override
        protected Transferable createTransferable(JComponent c) {
            TreePath selectionPath = jTree.getSelectionPath();
            if(c instanceof FilePanel){
                return new FileTransferable(((FilePanel) c).fileMutableTreeNode.file);
            }
            FileMutableTreeNode treeNode = (FileMutableTreeNode) selectionPath.getLastPathComponent();
            File file = treeNode.file;
            return new FileTransferable(file);
        }
    }


    /**
     * 显示选择tree 时 显示文件大图
     */
    private class FileViewPanel extends JPanel {
        /**
         * 当前显示的 FileMutableTreeNode
         */
        private FileMutableTreeNode fileMutableTreeNode;

        public FileViewPanel() {
            WrapLayout wrapLayout = new WrapLayout();
            wrapLayout.setAlignment(WrapLayout.LEFT);
            setLayout(wrapLayout);
            addMouseListener(new MouseAdapter() {
                @Override
                public void mouseClicked(MouseEvent e) {
                    if (SwingUtilities.isRightMouseButton(e)) {
                        showMenu(e);
                        return;
                    }
                }
            });
        }

        /**
         * 设置显示的 fileMutableTreeNode
         *
         * @param fileMutableTreeNode
         */
        void setFile(FileMutableTreeNode fileMutableTreeNode) {
            this.fileMutableTreeNode = fileMutableTreeNode;
            removeAll();
            for (int i = 0; i < fileMutableTreeNode.getChildCount(); i++) {
                FileMutableTreeNode childNode = (FileMutableTreeNode) fileMutableTreeNode.getChildAt(i);
                FilePanel filePanel = new FilePanel(childNode);
                add(filePanel);
            }
            fileViewPathBar.removeAll();
            while (fileMutableTreeNode!=null) {
                fileViewPathBar.add(new JLabel(fileMutableTreeNode.file.getName()),0);
                JLabel spl = new JLabel(">");
                fileViewPathBar.add(spl,1);
                fileMutableTreeNode=(FileMutableTreeNode)fileMutableTreeNode.getParent();
            }
            fileViewPathBar.revalidate();
            fileViewPathBar.repaint();
            revalidate();
            repaint();
        }

        /**
         * 显示空白地方的 菜单，不是选择文件时的
         *
         * @param event
         */
        void showMenu(MouseEvent event) {
            showResourcesPopupMenu(fileMutableTreeNode, event);
        }
    }
}
